package com.zx.JDK特性.jdk1_8;

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;
import java.util.stream.LongStream;
import org.springframework.util.StopWatch;

public class ForkJoinCalculate extends RecursiveTask<Long> {

    private static final long serialVersionUID = 6319418686810810828L;
    private static final long THRESHHOLD = 10_000;
    private long start;
    private long end;

    public ForkJoinCalculate(long start, long end) {
        this.start = start;
        this.end = end;
    }

    public static void main(String[] args) {
        long num = 100000000L;

        StopWatch sw = new StopWatch();

        sw.start("旧写法");
        long sum = 0L;
        for (int i = 0; i < 100000000L; i++) {
            sum++;
        }
        sw.stop();

        sw.start("JDK 1.7 写法");
        ForkJoinPool pool = new ForkJoinPool();
        ForkJoinTask<Long> task = new ForkJoinCalculate(0, num);
        pool.invoke(task);
        sw.stop();

        sw.start("JDK 1.8 写法");
        LongStream.rangeClosed(0, num)
                .parallel()//并行
                //.sequential()//串行
                .reduce(0, Long::sum);
        sw.stop();

        System.out.println(sw.prettyPrint());
    }

    @Override
    protected Long compute() {
        long length = end - start;

        if (length <= THRESHHOLD) {
            long sum = 0;
            for (long i = start; i <= end; i++) {
                sum += i;
            }
            return sum;
        } else {
            long middle = (start + end) / 2;

            ForkJoinCalculate left = new ForkJoinCalculate(start, middle);
            left.fork();

            ForkJoinCalculate right = new ForkJoinCalculate(middle + 1, end);
            right.fork();

            return left.join() + right.join();
        }
    }

}
